package com.quectel.cms.controller.grid;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.grid.GridMemberEvaluateBusiness;
import com.quectel.business.common.util.sys.SysCodeUtils;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.util.SessionHolder;
import com.quectel.constant.core.grid.GridConstant;
import com.quectel.constant.global.SystemConstants;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.constant.sys.SysCodeKeyConstants;
import com.quectel.core.module.grid.dto.GridDto;
import com.quectel.core.module.grid.dto.GridEventRecordDto;
import com.quectel.core.module.grid.dto.GridMemberEvaluateDto;
import com.quectel.core.module.grid.service.GridEventRecordService;
import com.quectel.core.module.grid.service.GridMemberEvaluateService;
import com.quectel.util.common.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author bob
 * @email bob.yu@quectel.com
 * @date 2023/02/03 15:45
 */
@RestController
@RequestMapping("gridMemberEvaluate")
@Tag(name = "GridMemberEvaluateController", description = "网格员评估表相关api")
public class GridMemberEvaluateController extends BaseController {

    @DubboReference
    private GridMemberEvaluateService gridMemberEvaluateService;
    @DubboReference
    private GridEventRecordService gridEventRecordService;
    @Autowired
    private GridMemberEvaluateBusiness gridMemberEvaluateBusiness;

    /**
     * 生成评估记录
     */
    @GetMapping("generate")
    @Operation(summary = "生成评估记录")
    @Log(express = "生成评估记录")
    public Response<Object> generate(@RequestParam(required = true) String assessYear) {

        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        Long tenantId = SessionHolder.getSysUser().getTenantId();

        gridMemberEvaluateBusiness.generateEvaluateRecord(tenantId, assessYear);
        return Response.ok();
    }

    /**
     * 评估打分操作
     *
     * @param dto
     * @return
     */
    @PostMapping("evaluate")
    @RequirePermissions(values = "gridMemberEvaluate:evaluate")
    @Operation(summary = "评估打分操作")
    @Log(express = "评估打分操作")
    public Response<Object> evaluate(@RequestBody GridMemberEvaluateDto dto) {
        GridMemberEvaluateDto gridMemberEvaluateDto = gridMemberEvaluateService.selectCacheById(dto.getId());
        if (gridMemberEvaluateDto == null) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        GridMemberEvaluateDto updately = new GridMemberEvaluateDto();
        updately.setId(dto.getId());
        updately.setAssessResult(dto.getAssessResult());
        updately.setAssessor(Objects.requireNonNull(SessionHolder.getSysUser()).getUsername());
        updately.setEvaluationTime(new Date());
        gridMemberEvaluateService.updateById(updately);
        return Response.ok();
    }


    /**
     * 导出网格员考核评估数据
     */
    @GetMapping("exportExcel")
    @RequirePermissions(values = "gridMemberEvaluate:exportExcel")
    @Operation(summary = "导出网格员考核评估数据")
    @Log(express = "导出网格员考核评估数据")
    public void exportExcel(@RequestParam Map<String, Object> params, HttpServletResponse hresp) {
        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(params);

        List<GridMemberEvaluateDto> result = new ArrayList<>();
        int pageNo = 0;
        params.put("limit", 1000);
        while (true) {
            params.put("offset", pageNo++ * 1000);
            List<GridMemberEvaluateDto> list = gridMemberEvaluateService.queryList(params);
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            if (list.size() < 1000) {
                break;
            }
        }
        String[] headers = new String[]{"评估年份", "姓名", "性别", "工号", "证件类型", "证件号", "手机号", "所属网格", "评估结果"};
        List<String[]> dataList = new ArrayList<>();
        for (GridMemberEvaluateDto data : result) {
            List<GridDto> grids = data.getGrids();
            if (CollectionUtils.isNotEmpty(grids)) {
                StringBuilder builder = new StringBuilder();
                for (GridDto grid : grids) {
                    StringBuilder append = builder.append(grid.getVillage().getStreetName()).append(grid.getVillage().getName()).append(grid.getName()).append(";");
                    data.setGridNameString(append.toString());
                }
            }

            String[] item = new String[headers.length];
            item[0] = data.getAssessYear();
            item[1] = data.getGridMember() != null ? data.getGridMember().getName() : null;
            item[2] = data.getGridMember() != null ? SysCodeUtils.easyToGetName(SysCodeKeyConstants.GENDER, data.getGridMember().getGender() + "") : null;
            item[3] = data.getGridMember() != null ? data.getGridMember().getJobNo() : null;
            item[4] = data.getGridMember() != null ? SysCodeUtils.easyToGetName(SysCodeKeyConstants.CARD_TYPE, data.getGridMember().getCardType() + "") : null;
            item[5] = data.getGridMember() != null ? data.getGridMember().getCardNo() : null;
            item[6] = data.getGridMember() != null ? data.getGridMember().getMobile() : null;
            item[7] = data.getGridNameString() != null ? data.getGridNameString() : null;
            item[8] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.GRID_MEMBER_EVALUATE, data.getAssessResult() + "");
            dataList.add(item);
        }
        POIUtils.exportExcel(hresp, "网格员考核评估", headers, dataList, "网格员考核评估");

    }


    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return 已办结的事件/总的事件,是办结率
     * 事件里面有个状态，是这个事件是否是逾期状态，所以逾期状态事件数量/总的事件，是逾期率
     * 事件驳回，触发驳回按钮的事件除以总事件是驳回率
     */
    @GetMapping("list")
    @RequirePermissions(values = "gridMemberEvaluate:list")
    @Operation(summary = "网格员评估的分页查询列表")
    public Response<Page<GridMemberEvaluateDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = gridMemberEvaluateService.queryTotal(request.getParams());

        List<GridMemberEvaluateDto> list = null;
        if (total > 0) {
            list = gridMemberEvaluateService.queryList(request.getParams());
            for (GridMemberEvaluateDto evaluateDto : list) {
                List<GridDto> grids = evaluateDto.getGrids();
                if (CollectionUtils.isNotEmpty(grids)) {
                    StringBuilder builder = new StringBuilder();
                    for (GridDto grid : grids) {
                        if (grid != null) {
                            StringBuilder append = builder.append(grid.getVillage().getStreetName()).append(grid.getVillage().getName()).append(grid.getName()).append(";");
                            evaluateDto.setGridNameString(append.toString());
                        }
                    }
                }

                String recordYear = evaluateDto.getAssessYear() + "-01-01";
                // 查询实时
                Map<String, Object> sqlMap = new HashMap<>();
                sqlMap.put(LambdaUtil.getFieldName(GridEventRecordDto::getGridMemberId), evaluateDto.getGridMemberId());
                sqlMap.put("startTime", DateUtils.format(DateUtil.beginOfYear(DateUtil.parseDate(recordYear)), DateUtils.FormatType.COMMON));
                sqlMap.put("endTime", DateUtils.format(DateUtil.endOfYear(DateUtil.parseDate(recordYear)), DateUtils.FormatType.COMMON));
                // 总的处理的事件
                List<GridEventRecordDto> totalList = gridEventRecordService.queryList(sqlMap);

                int eventTotal = totalList.size();
                if (eventTotal > 0) {
                    // 办结
                    int finishedTotal = (int) totalList.stream()
                            .filter(item -> item.getStatus().equals(GridConstant.GridEventRecordStatus.FINISHED.getStatus())).count();
                    // 驳回
                    int rejectedTotal = (int) totalList.stream()
                            .filter(item -> item.getStatus().equals(GridConstant.GridEventRecordStatus.REJECTED.getStatus())).count();
                    // 逾期
                    int expiredTotal = (int) totalList.stream()
                            .filter(item -> item.getStatus().equals(GridConstant.GridEventRecordStatus.EXPIRED.getStatus())).count();
                    DecimalFormat df = new DecimalFormat("0.00%");
                    BigDecimal dividend = new BigDecimal(eventTotal);

                    if (finishedTotal > 0) {
                        BigDecimal finished = new BigDecimal(finishedTotal);
                        BigDecimal recordfinishedResult = finished.divide(dividend, 2, BigDecimal.ROUND_HALF_UP);
                        String finishedRate = df.format(recordfinishedResult);
                        evaluateDto.setFinishedRate(finishedRate);
                    }

                    if (rejectedTotal > 0) {
                        BigDecimal rejected = new BigDecimal(rejectedTotal);
                        BigDecimal recordRejectedResult = rejected.divide(dividend, 2, BigDecimal.ROUND_HALF_UP);
                        String rejectedRate = df.format(recordRejectedResult);
                        evaluateDto.setRejectedRate(rejectedRate);
                    }

                    if (expiredTotal > 0) {
                        BigDecimal expired = new BigDecimal(expiredTotal);
                        BigDecimal recordExpiredResult = expired.divide(dividend, 2, BigDecimal.ROUND_HALF_UP);
                        String expiredRate = df.format(recordExpiredResult);
                        evaluateDto.setExpiredRate(expiredRate);
                    }
                }
            }
        } else {
            list = new ArrayList<>();
        }
        Page<GridMemberEvaluateDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<GridMemberEvaluateDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "gridMemberEvaluate:edit")
    @Operation(summary = "查询单条网格员评估记录")
    public Response<GridMemberEvaluateDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (gridMemberEvaluateService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        GridMemberEvaluateDto gridMemberEvaluateDto = gridMemberEvaluateService.selectById(id);

        return Response.<GridMemberEvaluateDto>ok().wrap(gridMemberEvaluateDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "gridMemberEvaluate:info")
    @Operation(summary = "查询单条网格员评估记录")
    public Response<GridMemberEvaluateDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (gridMemberEvaluateService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        GridMemberEvaluateDto gridMemberEvaluateDto = gridMemberEvaluateService.selectById(id);

        return Response.<GridMemberEvaluateDto>ok().wrap(gridMemberEvaluateDto);
    }

    /**
     * 保存
     *
     * @param gridMemberEvaluateDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "gridMemberEvaluate:edit")
    @Operation(summary = "保存单条网格员评估记录")
    public Response<Object> save(@RequestBody @Validated GridMemberEvaluateDto gridMemberEvaluateDto) {

        //填充基础数据
        fillSaveCommonData(gridMemberEvaluateDto);

        gridMemberEvaluateService.save(gridMemberEvaluateDto);

        return Response.ok();
    }


    /**
     * 修改
     *
     * @param gridMemberEvaluateDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "gridMemberEvaluate:edit")
    @Operation(summary = "修改单条网格员评估记录")
    public Response<Object> update(@RequestBody @Validated GridMemberEvaluateDto gridMemberEvaluateDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(gridMemberEvaluateDto.getId()));
        if (gridMemberEvaluateService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(gridMemberEvaluateDto);

        gridMemberEvaluateService.updateById(gridMemberEvaluateDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "gridMemberEvaluate:delete")
    @Operation(summary = "批量删除存在的网格员评估记录")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (gridMemberEvaluateService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        gridMemberEvaluateService.deleteBatch(ids);

        return Response.ok();
    }
}
